package com.jule.teenpatti.robot;

import com.jule.core.service.CronTaskManager;
import com.jule.core.service.ThreadPoolManager;
import com.jule.core.utils.xml.LogConfigUtils;
import com.jule.db.dao.CommDao;
import com.jule.db.entities.RobotCapitalPoolConfigModel;
import com.jule.db.entities.RobotHandCardConfigModel;
import com.jule.db.entities.User;
import com.jule.db.proxy.EntityProxy;
import com.jule.robot.Robot;
import com.jule.robot.config.Config;
import com.jule.robot.network.IOServer;
import com.jule.robot.service.LogService;
import com.jule.robot.service.PlayersService;
import com.jule.robot.service.PoolConfigService;
import com.jule.robot.service.holder.RobotUserHolder;
import com.jule.robot.service.holder.RoomConfigHolder;
import com.jule.robot.service.thread.*;
import com.jule.robot.valve.gate.RobotThreadPoolManager;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.List;
import java.util.function.Consumer;

@Slf4j
public class Main {

    public static void main(String[] args) throws InterruptedException {
        try {
            log.error("........................系统启动...........................");

            CronTaskManager.getInstance();
            LogConfigUtils.initLogConfig();
            Config.load();

            log.info("AUTH_SVR_URI -> " + Config.GATE_AUTH_SVR_URI);
            log.info("GATE_SVR_URI -> " + Config.GATE_SVR_URI);

            CommDao.OBJ.initDbConfig();

            LogService.OBJ.init(Config.LOG_URL);

            RoomConfigHolder.getInstance();

            PoolConfigService.OBJ.init().reset();

            if (Config.TEST_TYPE_IS_LOCAL == 0) {
                //退还异常机器人的货币
                RobotThreadPoolManager.getInstance().addTask(new ReturnRobotMoneyThread()); //异步执行
            }

            //初始化机器人列表
            RobotUserHolder.InitRobotUser();

            long t = new Date().getTime();

            //定时任务：输出线程池信息
            Consumer<Object> callThreadPool = obj -> {
                RobotThreadPoolManager.getInstance().addTask(new CheckThreadCount());
            };
            CronTaskManager.CountDownTask taskThreadPool = new CronTaskManager.CountDownTask(t, callThreadPool);
            CronTaskManager.getInstance().addCountDownJob(taskThreadPool.getName(), "CheckTimeoutRobotClient", taskThreadPool, "0 0/3 * * * ?");
            RobotThreadPoolManager.getInstance().addTask(new CheckThreadCount()); //启动时先执行一次

            //更新任务：机器人配置
            Consumer<Object> callRefreshConfig = obj -> {
                RobotThreadPoolManager.getInstance().addTask(new RefreshRoboConfigThread());
            };
            CronTaskManager.CountDownTask taskRefreshConfig = new CronTaskManager.CountDownTask(t, callRefreshConfig);
            CronTaskManager.getInstance().addCountDownJob(taskRefreshConfig.getName(), "refreshRoboConfigThread", taskRefreshConfig, "0 0/5 * * * ?");
            RobotThreadPoolManager.getInstance().addTask(new RefreshRoboConfigThread()); //启动时先执行一次

            //定时任务：检查机器人是否超时连接
            Consumer<Object> callTimeout = obj -> {
                RobotThreadPoolManager.getInstance().addTask(new CheckTimeoutRobotClient());
            };
            CronTaskManager.CountDownTask taskTimeout = new CronTaskManager.CountDownTask(t, callTimeout);
            CronTaskManager.getInstance().addCountDownJob(taskTimeout.getName(), "CheckTimeoutRobotClient", taskTimeout, "0 0/1 * * * ?");



            //如果允许机器人加入到空桌
            if (Config.ROBOT_JOIN_NULL_TABLE == 1) {
                //启动线程，监控桌子列表状态
                Consumer<Object> call = obj -> {
                        RobotThreadPoolManager.getInstance().addTask(new CheckNullTableIsNeedRobot(91001001));
                        RobotThreadPoolManager.getInstance().addTask(new CheckNullTableIsNeedRobot(91001002));
                        RobotThreadPoolManager.getInstance().addTask(new CheckNullTableIsNeedRobot(91001003));
                        RobotThreadPoolManager.getInstance().addTask(new CheckNullTableIsNeedRobot(91001004));
                        RobotThreadPoolManager.getInstance().addTask(new CheckNullTableIsNeedRobot(91001005));
                        RobotThreadPoolManager.getInstance().addTask(new CheckNullTableIsNeedRobot(91001006));
                };
                RobotThreadPoolManager.getInstance().addTask(new CheckNullTableIsNeedRobot(91001001));
                RobotThreadPoolManager.getInstance().addTask(new CheckNullTableIsNeedRobot(91001002));
                RobotThreadPoolManager.getInstance().addTask(new CheckNullTableIsNeedRobot(91001003));
                RobotThreadPoolManager.getInstance().addTask(new CheckNullTableIsNeedRobot(91001004));
                RobotThreadPoolManager.getInstance().addTask(new CheckNullTableIsNeedRobot(91001005));
                RobotThreadPoolManager.getInstance().addTask(new CheckNullTableIsNeedRobot(91001006));
                CronTaskManager.CountDownTask task = new CronTaskManager.CountDownTask(t, call);
                CronTaskManager.getInstance().addCountDownJob(task.getName(), "CheckNullTableIsNeedRobot", task, "0 0/"+Config.CHECK_THREAD_NULL_TABLEINTERVAL_MINUTE+" * * * ?");
            }


            //如果不是压测环境
            if (Config.TEST_TYPE_IS_STRESS == 0) {
                //启动线程，监控桌子列表状态
                //延迟50秒进行
                Consumer<Object> call = obj -> {
                        RobotThreadPoolManager.getInstance().addTask(new CheckTableIsNeedRobot(91001001));
                        RobotThreadPoolManager.getInstance().addTask(new CheckTableIsNeedRobot(91001002));
                        RobotThreadPoolManager.getInstance().addTask(new CheckTableIsNeedRobot(91001003));
                        RobotThreadPoolManager.getInstance().addTask(new CheckTableIsNeedRobot(91001004));
                        RobotThreadPoolManager.getInstance().addTask(new CheckTableIsNeedRobot(91001005));
                        RobotThreadPoolManager.getInstance().addTask(new CheckTableIsNeedRobot(91001006));
                };
                CronTaskManager.CountDownTask task = new CronTaskManager.CountDownTask(t, call);
                CronTaskManager.getInstance().addCountDownJob(task.getName(), "checkTableNeedRobot", task, "0/" + Config.CHECK_THREAD_INTERVAL_SEC + " * * * * ?");
            }

            //如果是压测环境
            if (Config.TEST_TYPE_IS_STRESS == 1) {
                Stress();
            }

            if(Config.TEST_TYPE_IS_LOCAL == 1){ //是本地环境
//                Consumer<Object> callReqIsHasAck  = obj -> {
//                    ThreadPoolManager.getInstance().addTask(new CheckReqIsHasAck());
//                };
//                long tt = new Date().getTime();
//                CronTaskManager.CountDownTask taskConfig = new CronTaskManager.CountDownTask(tt, callReqIsHasAck);
//                CronTaskManager.getInstance().addCountDownJob(taskConfig.getName(), "CheckReqIsHasAck", taskConfig, "0/2 * * * * ?");
            }

            IOServer.connect();

        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

    }

    private static void Stress() {
        int robotCnt = RobotUserHolder.getRobotMap().size();
        log.debug("StressTest robotCnt->{}", robotCnt);
        Consumer<Object> addRobotTask = obj -> {
            ThreadPoolManager.getInstance().addTask(new Runnable() {
                @Override
                public void run() {
                    if (PlayersService.getInstance().getOnlinePlayersNum() < Config.ROBOT_TOTAL_ROBOT_NUM) {
                        for (int i = 0; i < 1; i++) {
                            String userId = null;
                            try {
                                userId = RobotUserHolder.getUser("压力测试");
                            } catch (InterruptedException e1) {
                                log.error(e1.getMessage(),e1);
                            }
                            com.jule.db.entities.User user = EntityProxy.OBJ.get(userId, User.class);
                            settingMoney(user, 5000d);

                            new Robot(91001001, userId, null, null);
                        }
                    }
                }
            });
/*
                        ThreadPoolManager.getInstance().addTask(new Runnable() {
                            @Override
                            public void run() {
                                String userId = null;
                                try {
                                    userId = RobotUserHolder.getUser();
                                } catch (InterruptedException e1) {
                                }
                                com.jule.db.entities.User user = EntityProxy.OBJ.get(userId, com.jule.db.entities.User.class);
                                settingMoney(user, 5000L);

                                new Robot(91001002, userId, null, null);
                            }
                        });
                        ThreadPoolManager.getInstance().addTask(new Runnable() {
                            @Override
                            public void run() {
                                String userId = null;
                                try {
                                    userId = RobotUserHolder.getUser();
                                } catch (InterruptedException e1) {
                                }
                                com.jule.db.entities.User user = EntityProxy.OBJ.get(userId, com.jule.db.entities.User.class);
                                settingMoney(user, 5000L);

                                new Robot(91001003, userId, null, null);
                            }
                        });
                        ThreadPoolManager.getInstance().addTask(new Runnable() {
                            @Override
                            public void run() {
                                String userId = null;
                                try {
                                    userId = RobotUserHolder.getUser();
                                } catch (InterruptedException e1) {
                                }
                                com.jule.db.entities.User user = EntityProxy.OBJ.get(userId, com.jule.db.entities.User.class);
                                settingMoney(user, 5000L);

                                new Robot(91001004, userId, null, null);
                            }
                        });*/
        };
        long t = new Date().getTime();
        CronTaskManager.CountDownTask task = new CronTaskManager.CountDownTask(t, addRobotTask);
        CronTaskManager.getInstance().addCountDownJob(task.getName(), "addTableRobot", task, "0/" + Config.CHECK_THREAD_INTERVAL_SEC + " * * * * ?");

    }


    private static void settingMoney(com.jule.db.entities.User user, double score) {
//        User user = DBUtil.selectByPrimaryKey(userId);
        log.info("update id：" + user.getId() + ",money:" + user.getMoney() + ",score:" + score);
        if (user != null && user.getMoney() < score) {
            user.setMoney(score);
            log.info("update id：" + user.getId() + ",money:" + user.getMoney());
//            DBUtil.updateUser(user);
            EntityProxy.OBJ.update(user, com.jule.db.entities.User.class);
        }
    }
}
